#   This program is free software; you can redistribute it and/or modify
#   it under the terms of the version 3 of the GNU Lesser General Public License
#   as published by the Free Software Foundation.
#
#   This program is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#   GNU General Public License for more details.
#
#   You should have received a copy of the GNU Lesser General Public License
#   along with this program; if not, write to the Free Software
#   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#
# Copyright (c) NEC Deutschland GmbH, NEC HPC Europe
#
# $Id$
#
# You must run collectl with the "-A server" option!

import socket
from cStringIO import StringIO

from aggmon.importer import Importer
from basic_types.metric import Metric


__all__ = ["CollectlLexprImporter"]


class CollectlLexprImporter(Importer):
    def __init__( self, host_name="localhost", port=2655, **kwds ):        
        Importer.__init__( self, **kwds )
        # TODO: host name should be made more ... meaningful and unique
        self._host_name = host_name
        self._port = port

    def _parseCollectlLexpr( self, buffer ):
        samples = []
        for line in StringIO( buffer ).readlines():
            line_parts = line.strip().split( " " )                                                        
            if len( line_parts ) == 2:
                key = line_parts[0]
                try: value = float( line_parts[1] )
                except ValueError: continue
                
                if key == "sample.time":
                    samples.append( ( int( value ), {} ) )
                else:
                    samples[-1][1][key] = value

        for sample_time, key_values in samples:
            for key, value in key_values.iteritems():
                yield Metric( self._host_name, Metric( host=self._host_name, name=key, source="collectl", time=sample_time, value=value ) )

    def poll( self ):
        s = socket.socket( socket.AF_INET, socket.SOCK_STREAM )            
        s.connect( ( self._host_name, self._port ) )
                    
        while True:
            try:
                buffer = s.recv( 1024 )
                if len( buffer ) > 0:
                    for metric in self._parseCollectlLexpr( buffer ):
                        yield metric
                else:
                    break
            except IOError:
                break
